class Bluetooth {
	constructor() {
		this.isOpenBle = false; //是否蓝牙初始化完毕
		this.deviceId = "";
		this.serviceId = ""; //设备UUID	IOS
		this.servicesId = ""; //设备UUID 安卓
		this.notifyTId = ""; // FF02
		this.notifyId = "";
		this.connectType = false;
		this.stateType = false; //蓝牙是否连接成功
		this.callbackInformation = ""; //回调信息
		this.setIntervalList = []; //心跳数组对比
		this.notifyState = true; //notify是否启用
		this.equipmentData = {} //设备数据
		this.hideType = false //false 在APP内  true 在APP外

	}
	/**
	 * 公共弹框
	 * 
	 * @param {Object} title
	 * @param {Object} type
	 * @param {Object} time
	 */
	showToast(title, type = 'none', time = 2000) {
		uni.showToast({
			title: title,
			icon: type,
			'duration': time
		});
	}

	//判断蓝牙模块是否初始化完成
	judgInit() {
		if (!this.isOpenBle) {
			this.showToast(`初始化蓝牙模块失败`)
			return;
		}
	}

	//初始化蓝牙模块
	openBluetoothAdapter() {
		// this.judgInit()
		return new Promise((resolve, reject) => {
			uni.openBluetoothAdapter({
				success: res => {
					this.isOpenBle = true;
					// this.showToast("初始化蓝牙模块成功");
					resolve(res);
				},
				fail: err => {
					console.log(err)
					reject(err);
				},
			});
		})
	}

	//判断是否打开蓝牙
	getBluetoothAdapterState() {
		return new Promise((resolve, reject) => {
			uni.getBluetoothAdapterState({
				success: res => {
					resolve(res);
				},
				fail: err => {
					this.showToast(`请先打开蓝牙`);
					console.log(112, err)
					reject(err)
				}
			})
		})

	}
	/**
	 * 监听蓝牙设备是否断开、连接丢失、异常等
	 * 
	 * @param {Boolean} state 判断是否通过左上角返回造成连接断开
	 */
	onBLEConnectionStateChange() {
		let _this = this
		return new Promise((resolve, reject) => {
			console.log('开始监听是否断开')
			plus.bluetooth.onBLEConnectionStateChange((res) => {
				console.log('连接断开Ble', res)
				uni.setStorageSync('connectionFailed', true)
			})
		})
	}

	//开始搜素设备

	startBluetoothDevicesDiscovery() {
		this.judgInit()
		let deviceArray = []
		let _this = this
		return new Promise((resolve, reject) => {
			setTimeout(() => {
				uni.startBluetoothDevicesDiscovery({
					success: res => {
						uni.onBluetoothDeviceFound((onts) => {
							// console.log('-----onBluetoothDeviceFound------：' + JSON.stringify(res));
							for (let i = 0; i < onts.devices.length; i++) {
								if (onts.devices[i].name) {
									deviceArray.push(onts.devices[i]);
								}
							}
						});
					},
					fail: res => {
						_this.showToast(`搜索设备失败` + JSON.stringify(err));
						reject(err);
					}
				})
			}, 300);
		})
	}
	//停止搜索设备
	stopBluetoothDevicesDiscovery() {
		let _this = this;
		return new Promise((resolve, reject) => {
			uni.stopBluetoothDevicesDiscovery({
				success: e => {
					uni.hideLoading();
				},
				fail: e => {
					uni.hideLoading();
					_this.showToast(`停止搜索蓝牙设备失败` + JSON.stringify(err));
				}
			})
		});
	}
	/**
	 * 开始连接BLE蓝牙
	 * 
	 * @param {Object} deviceId 蓝牙中的deviceId
	 */
	createBLEConnection(deviceId) {
		console.log('deviceId', deviceId)
		uni.setStorageSync('deviceId', deviceId)
		this.deviceId = deviceId
		let _this = this
		uni.showLoading({
			mask: true,
			title: '设备连接中,请稍候...'
		})
		return new Promise((resolve, reject) => {
			uni.createBLEConnection({
				deviceId,
				timeout: 10000,
				success: (res) => {
					_this.connectType = true //连接成功
					console.log("res:createBLEConnection " + JSON.stringify(res));
					resolve(res)
				},
				fail: err => {
					uni.hideLoading();
					_this.showToast(`连接失败，请重新连接~`);
					console.log(123, JSON.stringify(err))
					reject(err);
				}
			})
		});
	}
	//信号强弱检测
	getBLEDeviceRSSI() {
		let deviceId = uni.getStorageSync('deviceId');
		let _this = this
		uni.getBLEDeviceRSSI({
			deviceId,
			success: res => {
				console.log(res)
			},
			fail: err => {
				console.log(err)
			},
		})
	}
	//获取设备所有服务
	getBLEDeviceServices() {
		let _serviceList = []; //数据处理
		let deviceId = uni.getStorageSync('deviceId');
		let _this = this
		return new Promise((resolve, reject) => {
			setTimeout(() => {
				uni.getBLEDeviceServices({
					deviceId,
					success: res => {
						console.log("获取设备所有服务成功", res)
						if (!res.services.length) {
							uni.hideLoading();
							reject(err);
						}
						for (let service of res.services) {
							if (service.isPrimary) {
								_serviceList.push(service);
							}
						}
						resolve(_serviceList)
					},
					fail: err => {
						uni.hideLoading();
						reject(err);
					},
				})
			}, 2000);
		});
	}
	// 获取服务中所有特征值
	getBLEDeviceCharacteristics(types) {

		let deviceId = uni.getStorageSync('deviceId');
		let serviceId;
		let _this = this;
		if (uni.getSystemInfoSync().platform == 'android') {
			serviceId = uni.getStorageSync('servicesId'); //安卓会返三个ID 需要拿第一个ID当作servicesId  第三个的ID拿取返回需要的值
		} else {
			serviceId = uni.getStorageSync('serviceId');
		}
		return new Promise((resolve, reject) => {
			uni.getBLEDeviceCharacteristics({
				deviceId,
				serviceId,
				success: res => {
					console.log(res)
					// if (uni.getSystemInfoSync().platform == 'android' && types == 2) {
					// 	uni.setStorageSync('serviceToId', res.characteristics[0].uuid);
					// 	resolve(true)
					// 	return false
					// }
					for (let _obj of res.characteristics) {
						//获取notify
						if (_obj.uuid.indexOf("FF01") != -1) {
							_this.notifyId = _obj.uuid;
							uni.setStorageSync('notifyId', _this.notifyId);
						}
						if (_obj.uuid.indexOf("FF02") != -1) {
							_this.notifyTId = _obj.uuid;
							uni.setStorageSync('notifyTId', _this.notifyTId);
						}
					}
					let result = {
						'notifyId': _this.notifyId
					};
					console.log("获取服务中所有特征值OK", uni.getStorageSync('notifyId'))
					resolve(result)
				},
				fail: err => {
					console.log('getBLEDeviceCharacteristics', JSON.stringify(err))
					_this.showToast(`getBLEDeviceCharacteristics` + JSON.stringify(err));
					reject(err);
				}
			})
		});
	}
	/*
	 * notify用的是FF01，notifyId
	 * 开始启用notify 功能
	 */
	notifyBLECharacteristicValue() {
		let deviceId = this.deviceId,
			serviceId,
			characteristicId = uni.getStorageSync('notifyId'),
			_this = this;
		console.log('deviceId', deviceId)
		if (uni.getSystemInfoSync().platform == 'android') {
			serviceId = uni.getStorageSync('servicesId');
		} else {
			serviceId = uni.getStorageSync('serviceId');
		}
		// console.log('characteristicId', notifyId)
		// console.log('serviceId', serviceId)
		return new Promise((resolve, reject) => {
			uni.notifyBLECharacteristicValueChange({
				state: _this.notifyState, // 启用 notify 功能
				deviceId,
				serviceId,
				characteristicId,
				success(res) {
					console.log('notify启用成功', JSON.stringify(res))
					_this.writeStr('5001010000000000') //启用notify后对设备进行握手
					setTimeout(() => {
						_this.onBLECharacteristicValueChange()
						resolve(res)
					}, 1000)
				},
				fail(res) {
					console.log('err', res)
					reject(res)
				}
			});
		})
	}

	//获取设备回调消息（必须要开启notify功能）
	onBLECharacteristicValueChange() {
		let _this = this
		plus.bluetooth.onBLECharacteristicValueChange(function(res) {
			// console.log('resss',res)
			if (res.value.byteLength > 4) {
				let data = _this.ab2hex(res.value)
				let sliceData = data.slice(data.indexOf('a') + 1)
				console.log('sliceData',sliceData)
				_this.onCallbackInformation(sliceData)
			}
		})
	}
	/**
	 * 返回数据给页面
	 * 
	 * @param {Object} value 握手返回设备信息
	 */
	onCallbackInformation(value) {
		var _this = this
		if (value) {
			uni.setStorageSync('callbackInformation', this.arrayProcessing(value))
		}
		if (uni.getStorageSync('callbackInformation')) {
			if (uni.getStorageSync('callbackInformation').length >= 11) {
				let arr = uni.getStorageSync('callbackInformation')
				let arrs = [] //心跳数据存储
				let identicalNum = 0 //相等值数量
				_this.equipmentData = {
					functionType: arr[0] == 1 ? '运行中' : '暂停中',
					functionTypeNum: arr[0],
					time: arr[1] + arr[2], //当前运行时间
					pattern: parseInt(arr[3]),
					batteryLevel: arr[4] == '00' ? '100' : arr[4],
					chargeType: arr[5] == 1 ? '充电中' : '未充电',
					fenType: arr[6] == 1 ? '异常' : '正常',
					temperature: (parseInt(`${arr[7]}${arr[8]}`, 16) - 2000) / 10, //体感温度
					wifiType: arr[9] == 1 ? '连接中' : arr[9] == 2 ? '连接成功' : '未连接', //wifi连接
					connectionFailed: uni.getStorageSync('connectionFailed'), //连接是否成功
				}
				console.log('equipmentData',_this.equipmentData)
				if (!_this.equipmentData.connectionFailed) {
					if (_this.setIntervalList.length <= 5) {
						_this.setIntervalList.push(_this.equipmentData.time)
						uni.setStorageSync('connectionFailed', false)
					} else {
						for (let i = 0; i < _this.setIntervalList.length; i++) {
							//需要第一个跟第二个数据进行比较 判断是否断开连接
							arrs.push(_this.setIntervalList[i])
							if (arrs.length >= 1) {
								if (arrs[i - 1] == _this.setIntervalList[i]) {
									identicalNum += 1
								}
							}
						}
						if (identicalNum >= 3) {
							//当有3条值或以上都相等的时候判定设备连接断开
							if (!_this.hideType) {
								// _this.connectionFailed = true
							}
						} else {
							_this.setIntervalList.shift()
							_this.connectionFailed = false
						}
					}
				}
				// console.log('dataa',_this.equipmentData)
				return _this.equipmentData
			}
		}
	}
	/**
	 * @param {Object} type true APP外  false APP内
	 */
	onHideType(type) {
		this.hideType = type
	}
	/**
	 * 将数据拆分[11, 11, 11...]
	 * 
	 * @param {Object} value 握手返回设备信息
	 */
	arrayProcessing(value) {
		let arr = [...value]
		let a, b;
		let aIndex = 0;
		let bIndex = 1;
		let arrs = [];
		arr.forEach((str, index) => {
			if (index % 2 === 0) {
				a = str;
				aIndex += 1
			} else {
				b = str
				bIndex += 1
			}
			if (a && b && (bIndex - aIndex === 1)) {
				arrs.push(a + b)
			}
		})
		return arrs
	}
	// 读取设备二进制数据
	readBLECharacteristicValue() {
		let _this = this
		let serviceId;
		if (uni.getSystemInfoSync().platform == 'android') {
			serviceId = uni.getStorageSync('servicesId');
		} else {
			serviceId = uni.getStorageSync('serviceId');
		}
		uni.readBLECharacteristicValue({
			deviceId: uni.getStorageSync('deviceId'),
			serviceId: serviceId,
			characteristicId: uni.getStorageSync('notifyId'),
			success: (res) => {
				console.log('进入readBLECharacteristicValue', res)
			},
			fail: (res) => {
				console.log('读取数据失败:', res)
			}
		})
	}

	/**
	 * 关闭蓝牙模块 断开所有连接并释放资源 
	 * 
	 */

	closeBluetoothAdapter() {
		let _this = this
		uni.closeBluetoothAdapter({
			success: res => {
				_this.notifyState = false
			},
			fail: err => {
				console.log(err)
			}
		});
	}
	/**
	 * 将指令转为arraybuffer
	 * 
	 * @param {Object} value 设备指令
	 */
	hexStringToArrayBuffers(value) {
		let str = value //需要传递给设备的指令
		let codeLength = str.length / 2;
		let buffer = new ArrayBuffer(codeLength);
		let dataView = new DataView(buffer)
		let ind = 0;
		for (let i = 0; i < str.length; i += 2) {
			let code = parseInt(str.substr(i, 2), 16)
			dataView.setUint8(ind, code)
			ind++
		}
		return buffer; //最终转为buffer指令 [object ArrayBuffer]
	}

	//断开连接释放资源后进行缓存数据清除并返回
	onCacheDataClearing() {
		let storage = ['deviceId', 'notifyId']
		uni.getSystemInfoSync().platform == 'android' ? storage.push('servicesId') : storage.push('serviceId')
		for (let i = 0; i < storage.length; i++) {
			uni.setStorageSync(storage[i], '')
		}
	}
	/**
	 * 发送指令，write是用的FF02 notifyTId
	 * 
	 * @param {Object} value 设备指令
	 */
	writeStr(value) {
		var _this = this;
		return new Promise((resolve, reject) => {
			let buffer = _this.hexStringToArrayBuffers(value)
			let abe = this.ab2hex(buffer) //解析结果 
			let serviceId;
			let deviceId = uni.getStorageSync('deviceId')
			if (uni.getSystemInfoSync().platform == 'android') {
				serviceId = uni.getStorageSync('servicesId')
			} else {
				serviceId = uni.getStorageSync('serviceId')
			}
			console.log('deviceId', deviceId)
			console.log('serviceId', serviceId)
			console.log('characteristicId', uni.getStorageSync('notifyTId'))
			console.log('buffer', buffer)
			setTimeout(() => {
				uni.writeBLECharacteristicValue({
					deviceId: deviceId,
					serviceId: serviceId,
					characteristicId: uni.getStorageSync('notifyTId'),
					value: buffer,
					success: (res) => {
						if (value == '5001010000000000') {
							_this.onBLEConnectionStateChange()
						}
						console.log('发送成功', res)
						_this.readBLECharacteristicValue();
						resolve(res)
					},
					fail: (res) => {
						console.log('发送失败', res)
						reject(res);
					},
					complete: (res) => {
						uni.hideLoading()
						console.log('发送结束', res)
						reject(res);
					}
				})
			}, 500)
		})
	}
	/**
	 * ArrayBuffer转16进度字符串
	 * 
	 * @param {Object} buffer 设备指令Buffer
	 */
	ab2hex(buffer) {
		const hexArr = Array.prototype.map.call(
			new Uint8Array(buffer),
			function(bit) {
				return ('00' + bit.toString(16)).slice(-2)
			}
		)
		return hexArr.join('')
	}

	//断开链接
	closeBLEConnection() {
		let deviceId = uni.getStorageSync('deviceId');
		console.log('断开蓝牙ID:', uni.getStorageSync('deviceId'))
		uni.setStorageSync('connectionFailed', false)
		let _this = this
		return new Promise((resolve, reject) => {
			uni.closeBLEConnection({
				deviceId,
				success(res) {
					resolve(res)
				},
				fail: err => {
					uni.hideLoading();
					reject(err);
				}
			})
		});

	}

}

export default Bluetooth
